package com.magiccompass.alipay.barcode.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.springframework.stereotype.Component;

import com.magiccompass.alipay.barcode.constants.BusinessLogicConstants;
import com.magiccompass.alipay.barcode.entity.MerchantBankAccount;
import com.magiccompass.alipay.barcode.model.DailySettlementDomesticBatchRecordModel;
import com.magiccompass.alipay.barcode.model.DailySettlementEmailModel;
import com.magiccompass.alipay.barcode.model.DailySettlementRecordModel;
import com.magiccompass.alipay.barcode.service.MerchantBusinessService;

@Component
public class DailySettlementDemosticBatchFileHandler {
	private static DailySettlementDemosticBatchFileHandler singleton = new DailySettlementDemosticBatchFileHandler();
	private DailySettlementDemosticBatchFileHandler(){}
	public static DailySettlementDemosticBatchFileHandler getInstance(){
		return singleton;
	}
	
	private static final String DAILY_SETTLEMENT_FILE_ROOT_PATH = "d:/alipay_barcode_daily_settlement_file/";
	
	// I've no idea why @Resource(name="merchantBusinessService") not working here.
	private MerchantBusinessService merchantBusinessService;
	
	public void startMakeBatchUploadFile(){
		makeReportFile(DailySettlementFileHandler.getInstance().getDailySettlementRecordsAdmin());
	}
	
	private void makeReportFile(List<DailySettlementRecordModel> data){
		if(data.size()>0){
			String fileName = "Admin_domestic_batch_"+DateTimeUtil.getYesterdayYYYYMMDDString()+".txt";
			String absoluteFileDirPath = getWriteToFilePath();
			
			File fileNewDir=new File(absoluteFileDirPath);
			if(!fileNewDir.exists()){
				fileNewDir.mkdirs();
			}
			File file = new File(absoluteFileDirPath+fileName);
			try(PrintWriter printWriter = new PrintWriter(file,"UTF-8")) {
				List<DailySettlementDomesticBatchRecordModel> dailySettlementDomesticBatchList = transferSettlementFile2BatchFile(data);
				
				boolean haveBatchUploadRecords = false;
				for(DailySettlementDomesticBatchRecordModel aRecord:dailySettlementDomesticBatchList){
					if(aRecord.getTransactionAmount().doubleValue()>0){ // TODO what if merchant has negative transaction amount? refund over income?
						printWriter.println(makeDetailLine(aRecord));
						haveBatchUploadRecords = true;
					}
				}
				
				if(haveBatchUploadRecords){
					DailySettlementEmailModel dsem = new DailySettlementEmailModel();
					
					dsem.setReceiverEmailAddress(BusinessLogicConstants.SYSTEM_ADMIN_EMAIL_ADDRESS);
					dsem.setReceiverName(BusinessLogicConstants.SYSTEM_ADMIN_NAME);
				
					dsem.setEmailTitle(DateTimeUtil.getYesterdayYYYYMMDDString()+" domestic batch upload file");
					dsem.setEmailBodyMessage("Hi "+dsem.getReceiverName()+", Attachment is yesterday settlement records for domestic batch upload.");
					dsem.setReportFileAbsolutePath(absoluteFileDirPath+fileName);
					DailySettlementFileEmailHandler.dailySettlementEmailBatchList.add(dsem);		
				}				
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private String makeDetailLine(DailySettlementDomesticBatchRecordModel aRow){
		StringBuffer sb = new StringBuffer();
		sb.append(aRow.getTransactionAmount()).append(",");
		sb.append(aRow.getAccountNumber()).append(",");
		sb.append(aRow.getOtherPartyName()).append(",");
		sb.append(aRow.getOriginatorReference()).append(",");
		sb.append(aRow.getOriginatorAnalysisCode()).append(",");
		sb.append(aRow.getOriginatorParticulars()).append(",");
		sb.append(aRow.getOtherPartyReference()).append(",");
		sb.append(aRow.getOtherAnalysisCode()).append(",");
		sb.append(aRow.getOtherParticulars());
		return sb.toString();
	}
	
	private String getWriteToFilePath(){
		StringBuffer sb = new StringBuffer();
		sb.append(DAILY_SETTLEMENT_FILE_ROOT_PATH);
		Timestamp yesterdayTime = DateTimeUtil.getYesterdayStartTime();
		sb.append(DateTimeUtil.formatTimeByFormat(yesterdayTime,"yyyy/MM/dd"));
		sb.append("/admin/");
		return sb.toString();
	}
	
	private List<DailySettlementDomesticBatchRecordModel> transferSettlementFile2BatchFile(List<DailySettlementRecordModel> settlementData){
		List<DailySettlementDomesticBatchRecordModel> returnData = new ArrayList<DailySettlementDomesticBatchRecordModel>();
		Integer currentMerchantId = 0;
		String currentMerchantName = "";
		BigDecimal eachMerchantTotalAmount = new BigDecimal(0);
		DailySettlementDomesticBatchRecordModel dsdbrm = new DailySettlementDomesticBatchRecordModel();
		for(DailySettlementRecordModel aRecord:settlementData){
			if(isTestMerchant(aRecord.getMerchantId().intValue(),aRecord.getMerchantName())){
				continue;
			}
			if(currentMerchantId.intValue() == 0){
				currentMerchantId = aRecord.getMerchantId();
				currentMerchantName = aRecord.getMerchantName();
				eachMerchantTotalAmount = aRecord.getSettlementAmount();
			}else if(currentMerchantId.intValue() != aRecord.getMerchantId().intValue()){
				dsdbrm = new DailySettlementDomesticBatchRecordModel();
				dsdbrm.setMerchantId(currentMerchantId);
				dsdbrm.setMerchantName(currentMerchantName);
				dsdbrm.setTransactionAmount(eachMerchantTotalAmount.setScale(2, RoundingMode.HALF_UP));
				dsdbrm.setAccountNumber(makeMerchantAccountBankFormat(currentMerchantId));
				dsdbrm.setOtherPartyName(makeMerchantNameBankFormat(currentMerchantName));
				
				dsdbrm.setOriginatorReference(makeOriginatorReference(currentMerchantName));
				dsdbrm.setOriginatorAnalysisCode(""); // TODO
				dsdbrm.setOriginatorParticulars(DateTimeUtil.getYesterdayDDMMYYYYString());
				dsdbrm.setOtherPartyReference(BusinessLogicConstants.BATCH_UPLOAD_REFERENCE);
				dsdbrm.setOtherAnalysisCode("");
				dsdbrm.setOtherParticulars(DateTimeUtil.getYesterdayDDMMYYYYString());
				returnData.add(dsdbrm);
				
				eachMerchantTotalAmount = aRecord.getSettlementAmount();
				currentMerchantId = aRecord.getMerchantId();
				currentMerchantName = aRecord.getMerchantName();
			}else{
				eachMerchantTotalAmount = eachMerchantTotalAmount.add(aRecord.getSettlementAmount());
			}
		}
		dsdbrm = new DailySettlementDomesticBatchRecordModel();
		dsdbrm.setMerchantId(currentMerchantId);
		dsdbrm.setMerchantName(currentMerchantName);
		dsdbrm.setTransactionAmount(eachMerchantTotalAmount.setScale(2, RoundingMode.HALF_UP));
		dsdbrm.setAccountNumber(makeMerchantAccountBankFormat(currentMerchantId));
		dsdbrm.setOtherPartyName(makeMerchantNameBankFormat(currentMerchantName));
		
		dsdbrm.setOriginatorReference(makeOriginatorReference(currentMerchantName));
		dsdbrm.setOriginatorAnalysisCode(""); // TODO
		dsdbrm.setOriginatorParticulars(DateTimeUtil.getYesterdayDDMMYYYYString());
		dsdbrm.setOtherPartyReference(BusinessLogicConstants.BATCH_UPLOAD_REFERENCE);
		dsdbrm.setOtherAnalysisCode(""); // TODO
		dsdbrm.setOtherParticulars(DateTimeUtil.getYesterdayDDMMYYYYString());
		returnData.add(dsdbrm);
		return returnData;		
	}
	
	private String makeMerchantAccountBankFormat(Integer merchantId){
		List<MerchantBankAccount> allMerchantBankAccount = merchantBusinessService.findAllActiveMerchantBankAccount(merchantId);
		StringBuffer sb = new StringBuffer();
		if(allMerchantBankAccount != null && allMerchantBankAccount.size()>0){
			MerchantBankAccount mba = allMerchantBankAccount.get(0);
			String accStr = mba.getAccountNumber();
			for(char aChar:accStr.toCharArray()){
				if(Pattern.matches("[0-9]",Character.toString(aChar))){
					sb.append(aChar);
				}
			}
		}
		return sb.toString();
	}
	
	private String makeMerchantNameBankFormat(String merchantName){
		if(merchantName.length()>20){
			return merchantName.substring(0, 20);
		}else{
			return merchantName;
		}
	}
	private String makeOriginatorReference(String merchantName){
		if(merchantName.length()>12){
			return merchantName.substring(0, 12);
		}else{
			return merchantName;
		}
	}
	
	public MerchantBusinessService getMerchantBusinessService() {
		return merchantBusinessService;
	}
	public void setMerchantBusinessService(MerchantBusinessService merchantBusinessService) {
		this.merchantBusinessService = merchantBusinessService;
	}
	
	private boolean isTestMerchant(int merchantId,String merchantName){
		int[] currentTestMerchantIdArray = {1,2};
		boolean returnValue = false;
		for(int i:currentTestMerchantIdArray){
			if(i == merchantId){
				returnValue = true;
				break;
			}
		}
		if(!returnValue){
			if(merchantName != null && merchantName.toLowerCase().contains("test")){
				returnValue = true;
			}
		}
		return returnValue;
	}
	
	public static void main(String[] args){
		DailySettlementDemosticBatchFileHandler d = new DailySettlementDemosticBatchFileHandler();
		System.out.println(d.isTestMerchant(2,"MC 03"));
		/*
		StringBuffer sb = new StringBuffer();
		String accStr = "06-0229-0615660-00";
		for(char aChar:accStr.toCharArray()){
			if(Pattern.matches("[0-9]",Character.toString(aChar))){
				sb.append(aChar);
			}
		}
		System.out.println(sb.toString());
		*/
		//String merchantName = "123456789012345678901234567890";
		//System.out.println(makeMerchantNameBankFormat(merchantName));
	}
}